//#include <iostream>
//using namespace std;
//
//class Base1
//{
//public:
//	virtual void func1() { cout << "Base1::func1" << endl; }
//	virtual void func2() { cout << "Base1::func2" << endl; }
//private:
//	int b1 = 1;
//};
//
//class Base2
//{
//public:
//	virtual void func1() { cout << "Base2::func1" << endl; }
//	virtual void func2() { cout << "Base2::func2" << endl; }
//private:
//	int b2 = 2;
//};
//
//class Derive : public Base1, public Base2
//{
//public:
//	virtual void func1() { cout << "Derive::func1" << endl; }
//	virtual void func3() { cout << "Derive::func3" << endl; }
//private:
//	int d1 = 3;
//};
//
//typedef void(*V_FUNC)(); // 把函数指针 void(*)() typedef 成 V_FUNC
//
//void Print_VFTable(V_FUNC* arr/*, size_t n*/)
//{
//	printf("vfptr:%p\n", arr);
//	for (size_t i = 0; arr[i] != nullptr/*i < n*/; ++i) // 如果编译器在最后无nullptr，就要手动传参，有几个就打印几个
//	{
//		printf("vfptr[%d]: %p\n", i, arr[i]);
//		V_FUNC Func = arr[i];
//		Func(); // 函数指针加括号->调用对应的函数
//	}
//	cout << endl;
//}
//int main()
//{
//	Derive d;
//	Print_VFTable((V_FUNC*)(*(int*)&d));
//
//	// 打印Base2的虚表先强转成char* +1 是+一个字节
//	Print_VFTable((V_FUNC*)(*(int*)((char*)&d + sizeof(Base1))));
//
//	printf("%p\n", &Derive::func1);
//
//	return 0;
//}

//#include<iostream>
//using namespace std;
//
//class Person
//{
//protected:
//    string _name = "李华";                // 姓名
//    string _num = "56465456456464";  // 身份证号
//};
//
//class Student : public Person
//{
//public:
//    void Print()
//    {
//        cout << "姓名：" << _name << endl;
//        cout << "身份证号：" << Person::_num << endl;  // 指定是Person的_num
//        cout << "学号：" << _num << endl;  // 默认在自己作用域内找_num
//    }
//protected:
//    string _num = "1007";  // 学号
//};
//
//int main(void)
//{
//    Student s1;
//    s1.Print();
//
//    return 0;
//}

//#include <iostream>
//using namespace std;
//
//class Person
//{
//public:
//    Person(const char* name)
//        : _name(name)
//    {
//        cout << "Person()" << endl;
//    }
//    ~Person() {
//        cout << "~Person()" << endl;
//    }
//
//protected:
//    string _name;
//};
//
//class Student : public Person
//{
//public:
//    Student(const char* name, int num)
//        : Person(name)  // 父类成员，调用自己的构造完成初始化
//        , _num(num)
//    {
//        cout << "Student()" << endl;
//    }
//
//    ~Student()
//    {
//        cout << "~Student()" << endl;
//
//        //Person::~Person();  
//        // 因为要先析构子类，所以不需要显示调用，编译器自动调用父类析构函数
//    }
//
//protected:
//    int _num;   // 学号
//};
//
//int main()
//{
//    Student s1("GR", 19);
//
//    return 0;
//}

//#include<iostream>
//using namespace std;
//
//class Student;
//class Person
//{
//public:
//	friend void Display(const Person& p, const Student& s);
//protected:
//	string _name; // 姓名
//};
//
//class Student : public Person
//{
//protected:
//	int _stuNum; // 学号
//};
//
//void Display(const Person& p, const Student& s)
//{
//	cout << p._name << endl;
//	cout << s._stuNum << endl; // 错误	C2248	“Student::_stuNum”: 无法访问 protected 成员(在“Student”类中声明)
//}
//
//void main()
//{
//	Person p;
//	Student s;
//	Display(p, s);
//}


//#include <iostream>
//using namespace std;
//
//class Person
//{
//public:
//	Person()
//	{
//		++_count;
//	}
//protected:
//	string _name; // 姓名
//public:
//	static int _count; // 统计人的个数
//};
//
//int Person::_count = 0;
//class Student : public Person
//{
//protected:
//	int _stuNum; // 学号
//};
//class Graduate : public Student
//{
//protected:
//	string _seminarCourse;
//};
//
//int main()
//{
//	Student s1;
//	Student s2;
//	Student s3;
//	Graduate s4;
//	Person s5;
//
//	cout << "大家都可以访问：(创建了多少个对象)" << endl;
//	cout << "人数：" << Person::_count << endl;
//	cout << "人数：" << Student::_count << endl;
//	cout << "人数：" << s4._count << endl;
//
//	cout << "顺便一个类把静态成员改变：" << endl;
//	s3._count = 0;
//	cout << "人数：" << Person::_count << endl;
//
//	cout << "并且他们的地址也都是一样的，因为所有继承体系中只有一个" << endl;
//	cout << "人数：" << &Person::_count << endl;
//	cout << "人数：" << &Student::_count << endl;
//	cout << "人数：" << &s4._count << endl;
//
//	return 0;
//}

#include <iostream>
using namespace std;

class Person
{
public:
	string _name; // 姓名
};

class Student : public Person
{
protected:
	int _num; //学号
};

class Teacher : public Person
{
protected:
	int _id; // 职工编号
};

class Assistant : public Student, public Teacher
{
protected:
	string _majorCourse; // 主修课程
};

int main()
{
	// 这样会有二义性无法明确知道访问的是哪一个
	Assistant a;
	//a._name = "peter"; // 错误	C2385	对“_name”的访问不明确

	// 需要显示指定访问哪个父类的成员可以解决二义性问题，但是数据冗余问题无法解决
	a.Student::_name = "GR";
	a.Teacher::_name = "RL";

	return 0;
}